package com.ideaaedi.zoo.diy.feature.msg.api.mq;

import com.ideaaedi.commonds.env.Env;
import com.ideaaedi.commonds.env.RequiredEnv;
import com.ideaaedi.commonds.env.Unit;
import com.ideaaedi.zoo.commonbase.face.Face;
import com.ideaaedi.zoo.diy.feature.msg.api.exception.MqNoSuchSenderException;
import com.ideaaedi.zoo.diy.feature.msg.api.exception.MqNotPointDefaultSenderException;
import com.ideaaedi.zoo.diy.feature.msg.api.exception.MqSendWayUnsupportException;
import com.ideaaedi.zoo.diy.feature.msg.api.mq.core.MqSender;
import com.ideaaedi.zoo.diy.feature.msg.api.mq.core.MqSenderManager;
import com.ideaaedi.zoo.diy.feature.msg.api.mq.entity.MqSendOption;
import com.ideaaedi.zoo.diy.feature.msg.api.mq.entity.MqSendResult;
import com.ideaaedi.zoo.diy.feature.msg.api.properties.ZooMsgProperties;
import lombok.experimental.UtilityClass;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * 消息队列门面工具类
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
@UtilityClass
public final class MqFaceUtil implements Face {
    
    static MqSenderManager mqSenderManager;
    
    static ZooMsgProperties zooMsgProperties;
    
    /**
     * 获取默认的mq发送器
     * <pre>
     * 你可以通过以下配置来指定默认的mq发送器
     * {@code
     *  zoo:
     *    msg:
     *       mq:
     *         # 指定mq的默认发送器
     *         default-sender-id: xxx
     * }
     * </pre>
     *
     * @return 默认的mq发送器
     */
    @Nullable
    @RequiredEnv(@Unit(Env.SPRING_BOOT))
    public static MqSender getDefaultSender() {
        return mqSenderManager.find(zooMsgProperties.getMq().getDefaultSenderId());
    }
    
    /**
     * 获取mq发送器管理器
     *
     * @return mq发送器管理器
     */
    @Nonnull
    @RequiredEnv(@Unit(Env.SPRING_BOOT))
    public static MqSenderManager getSenderManager() {
        return mqSenderManager;
    }
    
    /**
     * 普通mq发送
     *
     * @see #send(String, String, Object)
     *
     * @return 发送结果
     */
    @Nonnull
    @RequiredEnv(@Unit(Env.SPRING_BOOT))
    public static MqSendResult send(@Nonnull String channel, @Nonnull Object data) throws MqSendWayUnsupportException {
        String defaultSenderId = zooMsgProperties.getMq().getDefaultSenderId();
        if (StringUtils.isBlank(defaultSenderId)) {
            throw new MqNotPointDefaultSenderException("you could point default mq-sender by config 'zoo.msg.mq"
                    + ".default-sender-id=xxx'");
        }
        return send(defaultSenderId, channel, data);
    }
    
    /**
     * 普通mq发送
     *
     * @param senderId mq发送器id
     * @param channel 信道
     * @param data 数据
     *
     * @return 发送结果
     */
    @Nonnull
    @RequiredEnv(@Unit(Env.SPRING_BOOT))
    public static MqSendResult send(@Nonnull String senderId, @Nonnull String channel,
                                    @Nonnull Object data) throws MqSendWayUnsupportException {
        MqSender mqSender = mqSenderManager.find(senderId);
        if (mqSender == null) {
            throw new MqNoSuchSenderException("not found mq-sender whose id is '" + senderId + "'.");
        }
        return mqSender.send(channel, data);
    }
    
    /**
     * 普通mq发送
     *
     * @see #send(String, String, Object, MqSendOption)
     *
     * @return 发送结果
     */
    @Nonnull
    @RequiredEnv(@Unit(Env.SPRING_BOOT))
    public static MqSendResult send(@Nonnull String channel, @Nonnull Object data, @Nullable MqSendOption option)
            throws MqSendWayUnsupportException {
        String defaultSenderId = zooMsgProperties.getMq().getDefaultSenderId();
        if (StringUtils.isBlank(defaultSenderId)) {
            throw new MqNotPointDefaultSenderException("you could point default mq-sender by config 'zoo.msg.mq"
                    + ".default-sender-id=xxx'");
        }
        return send(defaultSenderId, channel, data, option);
    }
    
    /**
     * 发送
     *
     * @param senderId mq发送器id
     * @param channel 信道
     * @param data 数据
     * @param option 其余参数
     *
     * @return 发送结果
     */
    @Nonnull
    @RequiredEnv(@Unit(Env.SPRING_BOOT))
    public static MqSendResult send(@Nonnull String senderId, @Nonnull String channel, @Nonnull Object data,
                                    @Nullable MqSendOption option) throws MqSendWayUnsupportException {
        MqSender mqSender = mqSenderManager.find(senderId);
        if (mqSender == null) {
            throw new MqNoSuchSenderException("not found mq-sender whose id is '" + senderId + "'.");
        }
        return mqSender.send(channel, data, option);
    }
}
